package cn.wygandwdn.core.registry.nacos;

import cn.wygandwdn.common.config.RegistryConfig;
import cn.wygandwdn.common.enumeration.ErrorType;
import cn.wygandwdn.common.exception.RpcException;
import cn.wygandwdn.core.config.Config;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.*;

/**
 * @description:
 * @author: WYG
 * @time: 2021/10/31 10:56
 */

public class NacosUtil {
    private static final Logger log = LoggerFactory.getLogger(NacosUtil.class);

    private static final RegistryConfig config = Config.getConfig();
    private static final NamingService namingService;
    private static final Set<String> serviceNames = new HashSet<>();

    static {
        namingService = getNacosNamingService();
    }

    public static NamingService getNacosNamingService() {
        Properties properties = new Properties();
        properties.put("serverAddr", config.getAddress());
        if (config.getUsername() != null && config.getPassword() != null) {
            properties.put("username", config.getUsername());
            properties.put("password", config.getPassword());
        } else {
            properties.put("username", "nacos");
            properties.put("password", "nacos");
        }
        try {
            return NamingFactory.createNamingService(properties);
        } catch (NacosException e) {
            log.error("连接Nacos注册中心出错: {}", e);
            throw new RpcException(ErrorType.FAILED_CONNECT_REGISTRY);
        }
    }

    public static void registerService(String serviceName, String host, int port) throws NacosException {
        namingService.registerInstance(serviceName, host, port);
        serviceNames.add(serviceName);
    }

    /**
     * 获取所有实例
     * @param serviceName   服务名称
     * @return              实例
     * @throws NacosException
     */
    public static List<Instance> getAllInstances(String serviceName) throws NacosException {
        return namingService.getAllInstances(serviceName);
    }

    /**
     * 获取健康或者不健康的实例列表
     * @param serviceName   服务名称
     * @param healthy       是否健康
     * @return              健康or不健康的实例
     * @throws NacosException
     */
    public static List<Instance> getHealthyInstances(String serviceName, boolean healthy) throws NacosException {
        return namingService.selectInstances(serviceName, healthy);
    }

    public static void clearRegistry(String host, int port) {
        if (!serviceNames.isEmpty()) {
            Iterator<String> iterator = serviceNames.iterator();
            while (iterator.hasNext()) {
                String serviceName = iterator.next();
                try {
                    namingService.deregisterInstance(serviceName, host, port);
                } catch (NacosException e) {
                    log.error("注销服务失败: {}", e);
                }
            }
        }
    }
}
